﻿using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace RRRSRoguelikeData
{
	/// <summary>
	/// A class for reading text files.
	/// </summary>
	public static class Files
	{
		/// <summary>
		/// A method that returns a string containing the contents of the file.
		/// </summary>
		/// <param name="filePath"></param>
		/// <returns>A string containing the contents of the file. </returns>
		public static string TxtFileToString(string filePath)
		{
			string text;
			//needs to be more robust.  Error handling etc.
			try
			{
				var streamReader = new StreamReader(filePath);
				text = streamReader.ReadToEnd();
				streamReader.Close();
			}
			catch
			{
				text = Path.GetFileName(filePath) + " not available.";
			}

			return text;
		}


		public static TileData ReadFromXML(string filepath)
		{
			var tileData = new TileData();

			try
			{
				var TileSerializer = new XmlSerializer(typeof(TileData));

				var TileFileStream = new FileStream(filepath, FileMode.Open, FileAccess.Read);

				tileData = (TileData)TileSerializer.Deserialize(TileFileStream);
			}
			catch
			{
				tileData.ForeColor = "Red";
				tileData.BackColor = "White";
				tileData.ImageCharacter = "?";
				tileData.Name = "missing file";
				tileData.Description = "missing file: " + filepath;
				tileData.Walkable = true;

			}
			return tileData;

		}

		public static DungeonData ReadDataFromXML(string filepath)
		{
			var Data = new DungeonData();

			var XmlDoc = new XmlDocument();

			XmlDoc.Load(filepath);

			var Name = XmlDoc.GetElementsByTagName("Name");
			var Desription = XmlDoc.GetElementsByTagName("Description");
			var Sounds = XmlDoc.GetElementsByTagName("Sound");
			var Messages = XmlDoc.GetElementsByTagName("Message");
			var Players = XmlDoc.GetElementsByTagName("Player");
			var Creatures = XmlDoc.GetElementsByTagName("Creature");
			var Props = XmlDoc.GetElementsByTagName("Prop");
			var Tiles = XmlDoc.GetElementsByTagName("Tile");
			var Levels = XmlDoc.GetElementsByTagName("Level");

			Data.Name = Name[0].InnerText;
			Data.Description = Desription[0].InnerText;

			//this should load the txt from file
			foreach (XmlNode n in Messages)
				Data.Texts.Add(Path.GetFileNameWithoutExtension(n.InnerText),
					Files.TxtFileToString(Path.Combine(Path.GetDirectoryName(filepath), @n.InnerText)));

			foreach (XmlNode n in Sounds)
				Data.Sounds.Add(Path.GetFileNameWithoutExtension(n.InnerText),
					Path.Combine(Path.GetDirectoryName(filepath), @n.InnerText));
			
			foreach (XmlNode n in Players)
				Data.Players.Add(Path.GetFileNameWithoutExtension(n.InnerText),
					Files.ReadFromXML(Path.Combine(Path.GetDirectoryName(filepath), n.InnerText)));

			foreach (XmlNode n in Creatures)
				Data.Creatures.Add(Path.GetFileNameWithoutExtension(n.InnerText),
					Files.ReadFromXML(Path.Combine(Path.GetDirectoryName(filepath), n.InnerText)));

			foreach (XmlNode n in Props)
				Data.Props.Add(Path.GetFileNameWithoutExtension(n.InnerText),
					Files.ReadFromXML(Path.Combine(Path.GetDirectoryName(filepath), n.InnerText)));

			foreach (XmlNode n in Tiles)
				Data.Tiles.Add(Path.GetFileNameWithoutExtension(n.InnerText),
					Files.ReadFromXML(Path.Combine(Path.GetDirectoryName(filepath), n.InnerText)));

			foreach (XmlNode n in Levels)
				Data.Levels.Add(n.InnerText);


			return Data;

		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sourcePath"></param>
		/// <param name="targetPath"></param>
		/// <param name="overwrite"></param>
		public static void CopyFolder(string sourcePath, string targetPath, bool overwrite)
		{
			if (Directory.Exists(sourcePath))
			{
				var files = Directory.GetFiles(sourcePath);

				// Copy the files and overwrite destination files if they already exist. 
				foreach (var s in files)
				{
					// Use static Path methods to extract only the file name from the path.
					var fileName = Path.GetFileName(s);
					var destFile = Path.Combine(targetPath, fileName);

					//Create targetPath
					Directory.CreateDirectory(targetPath);

					if (overwrite || !File.Exists(destFile))
					{
						File.Copy(s, destFile, overwrite);
					}

				}
				var folders = Directory.GetDirectories(sourcePath);
				foreach (var s in folders)
				{
					var name = Path.GetFileName(s);
					var dest = Path.Combine(targetPath, name);
					CopyFolder(s, dest, false);
				}
			}
			else
			{
				//FIXME should be a localized string 
				Console.WriteLine("Source path does not exist!");
				Console.ReadKey();
			}
		}

	}
}
